package com.psytech.app.task.web_ui.driver;

import java.util.List;

import com.psytech.app.task.web_ui.Comment;
import com.psytech.app.task.web_ui.Task;
import com.psytech.app.task.web_ui.User;
import com.psytech.app.task.web_ui.driver.exception.InvalidCriteria;
import com.psytech.app.task.web_ui.driver.exception.ObjectNotFoundException;

/**
 * This interface describes all the methods that must implement the driver.
 * </br> The "TaskDriver" is the adapter between Taskman and the task
 * repository. </br>
 */
public interface TaskDriverInterface extends AuthInterface {

	/**
	 * Search tasks corresponding to the taskCriteria.
	 * 
	 * @param taskCriteria
	 *            each field not null is a criteria
	 * @return a task list corresponding to the criteria.
	 * @throws InvalidCriteria
	 *             if a field can't be use by the task repository to search a
	 *             task.
	 */
	List<Task> searchTask(Task taskCriteria) throws InvalidCriteria;

	/**
	 * Return the list of task assigned to the user.
	 * 
	 * @param users
	 *            cannot be null or empty.
	 * @return the list of the tasks assigned to the given user.
	 * @throws ObjectNotFoundException
	 *             if no task is assigned to the user.
	 * @throws IllegalArgumentException
	 *             if the user is null.
	 */
	List<Task> searchTasksAssignedToUsers(User user) throws ObjectNotFoundException, IllegalArgumentException;

	/**
	 * @param taskCriteria
	 *            each field not null is a criteria
	 * @return tasks not assigned matching the given task criteria.
	 * @throws ObjectNotFoundException
	 *             if no not assigned task match the taskCritera.
	 * @throws IllegalStateException
	 *             if the taskCriteria is null.
	 */
	List<Task> searchNotAssignedTasks(Task taskCriteria) throws ObjectNotFoundException, InvalidCriteria,
			IllegalArgumentException;

	/**
	 * Update a task description in the Master Data Service.
	 * 
	 * @param task
	 *            the task to update with at least the uid and the description
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task updateTaskDescription(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Update a task name in the Master Data Service.
	 * 
	 * @param task
	 *            the task to update with at least the uid and the name
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task updateTaskName(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Define the task as being in progress.
	 * 
	 * @param task
	 *            with at least the uid.
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task beginTask(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Define the task as being complete.
	 * 
	 * @param task
	 *            with at least the uid.
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task completeTask(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Define the task as pending.
	 * 
	 * @param task
	 *            with at least the uid.
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task suspendTask(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Set the expected end date
	 * 
	 * @param task
	 *            with at least the uid.
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task updateExpectedEndDate(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Set the expected start date
	 * 
	 * @param task
	 *            with at least the uid.
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task updateExpectedStartDate(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Assigns a task to the user and unassigns all other users
	 * 
	 * @param task
	 *            with at list the uid and the assignedUserUid.
	 * @return the persisted tasks
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task assignsTaskToUser(Task task) throws ObjectNotFoundException, IllegalArgumentException;

	/**
	 * Create a task in the Master Data Service.
	 * 
	 * @param task
	 *            the task to persist with at least the name, description and
	 *            creator uid.
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 */
	Task createTask(Task task) throws IllegalArgumentException;

	/**
	 * Define the task as a priority.
	 * 
	 * @param task
	 *            with at least the uid.
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task increasePriority(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Define as non-priority task.
	 * 
	 * @param task
	 *            with at least the uid.
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	Task lowPriority(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Undifine the priority of the task.
	 * 
	 * @param task
	 *            with at least the uid.
	 * @return the persisted task
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundExceptionif
	 *             the task don't exist.
	 */
	Task unSpecifiPriority(Task task) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Remove a task from the Master Data Service.
	 * 
	 * @param task
	 *            the task you want to remove.
	 * @throws IllegalArgumentException
	 *             if the object in invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 */
	void deleteTask(Task task) throws ObjectNotFoundException, IllegalArgumentException;

	/**
	 * Get all comments linked to a task.
	 * 
	 * @param task
	 *            the task for which we want to retrieve comments.
	 * @return all comments linked to the task.
	 * @throws ObjectNotFoundException
	 *             if the task don't exist.
	 * @throws IllegalArgumentException
	 *             if task or the uid are null.
	 */
	List<Comment> getCommentsByTask(Task task) throws ObjectNotFoundException, IllegalArgumentException;

	/**
	 * Insert a comment into the Master Data Service.
	 * 
	 * @param comment
	 *            the comment to insert.
	 * @return the persisted comment.
	 * @throws IllegalArgumentException
	 *             if the object is invalid i.e. the object does not comply to
	 *             the constraints of referential.
	 * @throws ObjectNotFoundException
	 *             if the taskUid don't refer to an existing task.
	 */
	Comment createComment(Comment comment) throws IllegalArgumentException, ObjectNotFoundException;

	/**
	 * Remove a comment.
	 * 
	 * @param comment
	 *            the comment you want to remove.
	 * @throws ObjectNotFoundException
	 *             if the commentUid don't refer to an existing comment.
	 */
	void deleteComment(Comment comment) throws ObjectNotFoundException;

}
